﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Common.Extensions/ExpressionExtensions 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       ExpressionExtensions
* 创建时间：  2025/5/22 15:11:11
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion 
using SSPivot.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using SSPivot;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using SSPivot.Common.Helpers;

namespace System.Linq
{
    public static class ExpressionExtensions
    {
        #region 辅助方法

        private static string DealExpress(Expression exp)
        {
            if (exp is LambdaExpression)
            {
                LambdaExpression l_exp = exp as LambdaExpression;
                return DealExpress(l_exp.Body);
            }
            if (exp is BinaryExpression)
            {
                return DealBinaryExpression(exp as BinaryExpression);
            }
            if (exp is MemberExpression)
            {
                return DealMemberExpression(exp as MemberExpression);
            }
            if (exp is ConstantExpression)
            {
                return DealConstantExpression(exp as ConstantExpression);
            }
            if (exp is UnaryExpression)
            {
                return DealUnaryExpression(exp as UnaryExpression);
            }
            return "";
        }

        private static string DealUnaryExpression(UnaryExpression exp)
        {
            return DealExpress(exp.Operand);
        }
        private static string DealConstantExpression(ConstantExpression exp)
        {
            object vaule = exp.Value;
            string v_str = string.Empty;
            if (vaule == null)
            {
                return "NULL";
            }
            if (vaule is string)
            {
                v_str = string.Format("'{0}'", vaule.ToString());
            }
            else if (vaule is DateTime)
            {
                DateTime time = (DateTime)vaule;
                v_str = string.Format("'{0}'", time.ToString("yyyy-MM-dd HH:mm:ss"));
            }
            else
            {
                v_str = vaule.ToString();
            }
            return v_str;
        }
        private static string DealBinaryExpression(BinaryExpression exp)
        {

            string left = DealExpress(exp.Left);
            string oper = GetOperStr(exp.NodeType);
            string right = DealExpress(exp.Right);
            if (right == "NULL")
            {
                if (oper == "=")
                {
                    oper = " is ";
                }
                else
                {
                    oper = " is not ";
                }
            }
            return left + oper + right;
        }
        private static string DealMemberExpression(MemberExpression exp)
        {
            return exp.Member.Name;
        }
        private static string GetOperStr(ExpressionType e_type)
        {
            switch (e_type)
            {
                case ExpressionType.OrElse: return " OR ";
                case ExpressionType.Or: return "|";
                case ExpressionType.AndAlso: return " AND ";
                case ExpressionType.And: return "&";
                case ExpressionType.GreaterThan: return ">";
                case ExpressionType.GreaterThanOrEqual: return ">=";
                case ExpressionType.LessThan: return "<";
                case ExpressionType.LessThanOrEqual: return "<=";
                case ExpressionType.NotEqual: return "<>";
                case ExpressionType.Add: return "+";
                case ExpressionType.Subtract: return "-";
                case ExpressionType.Multiply: return "*";
                case ExpressionType.Divide: return "/";
                case ExpressionType.Modulo: return "%";
                case ExpressionType.Equal: return "=";
            }
            return "";
        }
         
        #endregion

        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="query"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="sortType"></param>
        /// <returns></returns>
        public static IOrderedQueryable<TElement> SortBy<TElement>(this IQueryable<TElement> query, string orderByExpression, SortType sortType)
        {
            var property = GetPropertieByName(query.ElementType, orderByExpression);
            var parameter = Expression.Parameter(typeof(TElement), null);
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);
            string methodName = sortType == SortType.Desc ? "OrderByDescending" : "OrderBy";
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { typeof(TElement), property.PropertyType }, query.Expression, Expression.Quote(orderByExp));
            query = query.Provider.CreateQuery<TElement>(resultExp);
            return (IOrderedQueryable<TElement>)query;
        }

        private static PropertyInfo GetPropertieByName(Type elementType, string elementName)
        {
            return elementType.GetProperties().Where(e => e.Name.ToLower() == elementName.ToLower()).FirstOrDefault();
        }


        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="query"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="sortType"></param>
        /// <returns></returns>
        public static IOrderedQueryable<TElement> SortThenBy<TElement>(this IOrderedQueryable<TElement> query, string orderByExpression, SortType sortType)
        {
            var property = GetPropertieByName(query.ElementType, orderByExpression);
            var parameter = Expression.Parameter(typeof(TElement), null);
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);
            string methodName = sortType == SortType.Desc ? "ThenByDescending" : "ThenBy";
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { typeof(TElement), property.PropertyType }, query.Expression, Expression.Quote(orderByExp));
            query = (IOrderedQueryable<TElement>)query.Provider.CreateQuery<TElement>(resultExp);
            return query;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="query"></param>
        /// <param name="selector"></param>
        /// <returns></returns>
        public static IOrderedQueryable<TElement> SortBy<TElement, TKey>(this IQueryable<TElement> query, Dictionary<Expression<Func<TElement, TKey>>, SortType> selector)
        {
            IOrderedQueryable<TElement> result = null;
            if (selector == null || selector.Count <= 0) throw new ArgumentNullException("排序字段不能为空");
            int i = 0;
            foreach (var item in selector)
            {
                var elementName = DealExpress(item.Key);
                if (i > 0)
                { 
                    result = result.SortThenBy(elementName, item.Value);
                }
                else
                { 
                    result = query.SortBy(elementName, item.Value);
                }
                i++;
            }
            return result;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="query"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        public static IQueryable<TElement> PageBy<TElement>(this IOrderedQueryable<TElement> query, IPageResult page)
        {
            if (page == null) page = PageResult.Default();
            return query.Skip((page.PageNo - 1) * page.PageSize).Take(page.PageSize);
        }

        public static IQueryable<TElement> WhereIf<TElement>(this IQueryable<TElement> query, bool condition, Expression<Func<TElement, bool>> predicate)
        {
            if (!condition)
            {
                return query;
            }
            return query.Where(predicate);
        }

        #region GetType(获取类型)

        /// <summary>
        /// 获取类型
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name</param>
        public static Type GetType(this Expression expression)
        {
            var memberExpression = GetMemberExpression(expression);
            return memberExpression?.Type;
        }

        #endregion

        #region GetMember(获取成员)

        /// <summary>
        /// 获取成员
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name</param>
        public static MemberInfo GetMember(this Expression expression)
        {
            var memberExpression = GetMemberExpression(expression);
            return memberExpression?.Member;
        }

        /// <summary>
        /// 获取成员表达式
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="right">取表达式右侧,(l,r) => l.id == r.id，设置为true,返回r.id表达式</param>
        public static MemberExpression GetMemberExpression(this Expression expression, bool right = false)
        {
            if (expression == null)
                return null;
            switch (expression.NodeType)
            {
                case ExpressionType.Lambda:
                    return GetMemberExpression(((LambdaExpression)expression).Body, right);
                case ExpressionType.Convert:
                case ExpressionType.Not:
                    return GetMemberExpression(((UnaryExpression)expression).Operand, right);
                case ExpressionType.MemberAccess:
                    return (MemberExpression)expression;
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.LessThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.LessThanOrEqual:
                    return GetMemberExpression(right ? ((BinaryExpression)expression).Right : ((BinaryExpression)expression).Left, right);
                case ExpressionType.Call:
                    return GetMethodCallExpressionName(expression);
            }
            return null;
        }

        /// <summary>
        /// 获取方法调用表达式的成员名称（有问题）
        /// </summary>
        private static MemberExpression GetMethodCallExpressionName(this Expression expression)
        {
            var methodCallExpression = (MethodCallExpression)expression;
            var left = (MemberExpression)methodCallExpression.Object;
            //if (System.Reflection.IsGenericCollection(left?.Type))
            //{
            //    var argumentExpression = methodCallExpression.Arguments.FirstOrDefault();
            //    if (argumentExpression != null && argumentExpression.NodeType == ExpressionType.MemberAccess)
            //        return (MemberExpression)argumentExpression;
            //}
            return left;
        }

        #endregion

        #region GetName(获取成员名称)

        /// <summary>
        /// 获取成员名称，范例：t => t.A.Name,返回 A.Name
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name</param>
        public static string GetName(this Expression expression)
        {
            var memberExpression = GetMemberExpression(expression);
            return GetMemberName(memberExpression);
        }

        /// <summary>
        /// 获取成员名称
        /// </summary>
        public static string GetMemberName(this MemberExpression memberExpression)
        {
            if (memberExpression == null)
                return string.Empty;
            string result = memberExpression.ToString();
            return result.Substring(result.IndexOf(".", StringComparison.Ordinal) + 1);
        }

        #endregion

        #region GetNames(获取名称列表)

        /// <summary>
        /// 获取名称列表，范例：t => new object[] { t.A.B, t.C },返回A.B,C
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="expression">属性集合表达式,范例：t => new object[]{t.A,t.B}</param>
        public static List<string> GetNames<T>(this Expression<Func<T, object[]>> expression)
        {
            var result = new List<string>();
            if (expression == null)
                return result;
            if (!(expression.Body is NewArrayExpression arrayExpression))
                return result;
            foreach (var each in arrayExpression.Expressions)
            {
                var name = GetName(each);
                if (string.IsNullOrWhiteSpace(name) == false)
                    result.Add(name);
            }
            return result;
        }

        #endregion

        #region GetLastName(获取最后一级成员名称)

        /// <summary>
        /// 获取最后一级成员名称，范例：t => t.A.Name,返回 Name
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name</param>
        /// <param name="right">取表达式右侧,(l,r) => l.LId == r.RId，设置为true,返回RId</param>
        public static string GetLastName(this Expression expression, bool right = false)
        {
            var memberExpression = GetMemberExpression(expression, right);
            if (memberExpression == null)
                return string.Empty;
            if (IsValueExpression(memberExpression))
                return string.Empty;
            string result = memberExpression.ToString();
            return result.Substring(result.LastIndexOf(".", StringComparison.Ordinal) + 1);
        }

        /// <summary>
        /// 是否值表达式
        /// </summary>
        /// <param name="expression">表达式</param>
        private static bool IsValueExpression(this Expression expression)
        {
            if (expression == null)
                return false;
            switch (expression.NodeType)
            {
                case ExpressionType.MemberAccess:
                    return IsValueExpression(((MemberExpression)expression).Expression);
                case ExpressionType.Constant:
                    return true;
            }
            return false;
        }

        #endregion

        #region GetLastNames(获取最后一级成员名称列表)

        /// <summary>
        /// 获取最后一级成员名称列表，范例：t => new object[] { t.A.B, t.C },返回B,C
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="expression">属性集合表达式,范例：t => new object[]{t.A,t.B}</param>
        public static List<string> GetLastNames<T>(this Expression<Func<T, object[]>> expression)
        {
            var result = new List<string>();
            if (expression == null)
                return result;
            if (!(expression.Body is NewArrayExpression arrayExpression))
                return result;
            foreach (var each in arrayExpression.Expressions)
            {
                var name = GetLastName(each);
                if (string.IsNullOrWhiteSpace(name) == false)
                    result.Add(name);
            }
            return result;
        }

        #endregion

        #region GetValue(获取值)

        /// <summary>
        /// 获取值,范例：t => t.Name == "A",返回 A
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name == "A"</param>
        public static object GetValue(this Expression expression)
        {
            if (expression == null)
                return null;
            switch (expression.NodeType)
            {
                case ExpressionType.Lambda:
                    return GetValue(((LambdaExpression)expression).Body);
                case ExpressionType.Convert:
                    return GetValue(((UnaryExpression)expression).Operand);
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.LessThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.LessThanOrEqual:
                    var hasParameter = HasParameter(((BinaryExpression)expression).Left);
                    if (hasParameter)
                        return GetValue(((BinaryExpression)expression).Right);
                    return GetValue(((BinaryExpression)expression).Left);
                case ExpressionType.Call:
                    return GetMethodCallExpressionValue(expression);
                case ExpressionType.MemberAccess:
                    return GetMemberValue((MemberExpression)expression);
                case ExpressionType.Constant:
                    return GetConstantExpressionValue(expression);
                case ExpressionType.Not:
                    if (expression.Type == typeof(bool))
                        return false;
                    return null;
            }
            return null;
        }

        /// <summary>
        /// 是否包含参数，用于检测是属性，而不是值
        /// </summary>
        private static bool HasParameter(this Expression expression)
        {
            if (expression == null)
                return false;
            switch (expression.NodeType)
            {
                case ExpressionType.Convert:
                    return HasParameter(((UnaryExpression)expression).Operand);
                case ExpressionType.MemberAccess:
                    return HasParameter(((MemberExpression)expression).Expression);
                case ExpressionType.Parameter:
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 获取方法调用表达式的值
        /// </summary>
        private static object GetMethodCallExpressionValue(this Expression expression)
        {
            var methodCallExpression = (MethodCallExpression)expression;
            var value = GetValue(methodCallExpression.Arguments.FirstOrDefault());
            if (value != null)
                return value;
            if (methodCallExpression.Arguments.Count > 1)
                return GetValue(methodCallExpression.Arguments[1]);
            if (methodCallExpression.Object == null)
                return methodCallExpression.Type.InvokeMember(methodCallExpression.Method.Name, BindingFlags.InvokeMethod, null, null, null);
            return GetValue(methodCallExpression.Object);
        }

        /// <summary>
        /// 获取属性表达式的值
        /// </summary>
        private static object GetMemberValue(this MemberExpression expression)
        {
            if (expression == null)
                return null;
            var field = expression.Member as FieldInfo;
            if (field != null)
            {
                var constValue = GetConstantExpressionValue(expression.Expression);
                return field.GetValue(constValue);
            }
            var property = expression.Member as PropertyInfo;
            if (property == null)
                return null;
            if (expression.Expression == null)
                return property.GetValue(null);
            if (expression.Expression is ConstantExpression)
            {
                var constValue = GetConstantExpressionValue(expression.Expression);
                return property.GetValue(constValue);
            }
            var value = GetMemberValue(expression.Expression as MemberExpression);
            if (value == null)
            {
                if (property.PropertyType == typeof(bool))
                    return true;
                return null;
            }
            return property.GetValue(value);
        }

        /// <summary>
        /// 获取常量表达式的值
        /// </summary>
        private static object GetConstantExpressionValue(this Expression expression)
        {
            var constantExpression = (ConstantExpression)expression;
            return constantExpression.Value;
        }

        #endregion

        #region GetOperator(获取查询操作符)

        /// <summary>
        /// 获取查询操作符,范例：t => t.Name == "A",返回 Operator.Equal
        /// </summary>
        /// <param name="expression">表达式,范例：t => t.Name == "A"</param>
        public static Operator? GetOperator(this Expression expression)
        {
            if (expression == null)
                return null;
            switch (expression.NodeType)
            {
                case ExpressionType.Lambda:
                    return GetOperator(((LambdaExpression)expression).Body);
                case ExpressionType.Convert:
                    return GetOperator(((UnaryExpression)expression).Operand);
                case ExpressionType.Equal:
                    return Operator.Equal;
                case ExpressionType.NotEqual:
                    return Operator.NotEqual;
                case ExpressionType.GreaterThan:
                    return Operator.Greater;
                case ExpressionType.LessThan:
                    return Operator.Less;
                case ExpressionType.GreaterThanOrEqual:
                    return Operator.GreaterEqual;
                case ExpressionType.LessThanOrEqual:
                    return Operator.LessEqual;
                case ExpressionType.Call:
                    return GetMethodCallExpressionOperator(expression);
            }
            return null;
        }

        /// <summary>
        /// 获取方法调用表达式的值
        /// </summary>
        private static Operator? GetMethodCallExpressionOperator(this Expression expression)
        {
            var methodCallExpression = (MethodCallExpression)expression;
            switch (methodCallExpression?.Method?.Name?.ToLower())
            {
                case "contains":
                    return Operator.Contains;
                case "endswith":
                    return Operator.Ends;
                case "startswith":
                    return Operator.Starts;
            }
            return null;
        }

        #endregion

        #region GetParameter(获取参数)

        /// <summary>
        /// 获取参数，范例：t.Name,返回 t
        /// </summary>
        /// <param name="expression">表达式，范例：t.Name</param>
        public static ParameterExpression GetParameter(this Expression expression)
        {
            if (expression == null)
                return null;
            switch (expression.NodeType)
            {
                case ExpressionType.Lambda:
                    return GetParameter(((LambdaExpression)expression).Body);
                case ExpressionType.Convert:
                    return GetParameter(((UnaryExpression)expression).Operand);
                case ExpressionType.Equal:
                case ExpressionType.NotEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.LessThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.LessThanOrEqual:
                    return GetParameter(((BinaryExpression)expression).Left);
                case ExpressionType.MemberAccess:
                    return GetParameter(((MemberExpression)expression).Expression);
                case ExpressionType.Call:
                    return GetParameter(((MethodCallExpression)expression).Object);
                case ExpressionType.Parameter:
                    return (ParameterExpression)expression;
            }
            return null;
        }

        #endregion

        #region GetGroupPredicates(获取分组的谓词表达式)

        /// <summary>
        /// 获取分组的谓词表达式，通过Or进行分组
        /// </summary>
        /// <param name="expression">谓词表达式</param>
        public static List<List<Expression>> GetGroupPredicates(this Expression expression)
        {
            var result = new List<List<Expression>>();
            if (expression == null)
                return result;
            AddPredicates(expression, result, CreateGroup(result));
            return result;
        }

        /// <summary>
        /// 创建分组
        /// </summary>
        private static List<Expression> CreateGroup(this List<List<Expression>> result)
        {
            var gourp = new List<Expression>();
            result.Add(gourp);
            return gourp;
        }

        /// <summary>
        /// 添加通过Or分割的谓词表达式
        /// </summary>
        private static void AddPredicates(this Expression expression, List<List<Expression>> result, List<Expression> group)
        {
            switch (expression.NodeType)
            {
                case ExpressionType.Lambda:
                    AddPredicates(((LambdaExpression)expression).Body, result, group);
                    break;
                case ExpressionType.OrElse:
                    AddPredicates(((BinaryExpression)expression).Left, result, group);
                    AddPredicates(((BinaryExpression)expression).Right, result, CreateGroup(result));
                    break;
                case ExpressionType.AndAlso:
                    AddPredicates(((BinaryExpression)expression).Left, result, group);
                    AddPredicates(((BinaryExpression)expression).Right, result, group);
                    break;
                default:
                    group.Add(expression);
                    break;
            }
        }

        #endregion

        #region GetConditionCount(获取查询条件个数)

        /// <summary>
        /// 获取查询条件个数
        /// </summary>
        /// <param name="expression">谓词表达式,范例1：t => t.Name == "A" ，结果1。
        /// 范例2：t => t.Name == "A" &amp;&amp; t.Age =1 ，结果2。</param>
        public static int GetConditionCount(this LambdaExpression expression)
        {
            if (expression == null)
                return 0;
            var result = expression.ToString().Replace("AndAlso", "|").Replace("OrElse", "|");
            return result.Split('|').Count();
        }

        #endregion

        #region GetAttribute(获取特性)

        /// <summary>
        /// 获取特性
        /// </summary>
        /// <typeparam name="TAttribute">特性类型</typeparam>
        /// <param name="expression">属性表达式</param>
        public static TAttribute GetAttribute<TAttribute>(this Expression expression) where TAttribute : Attribute
        {
            var memberInfo = GetMember(expression);
            return memberInfo.GetCustomAttribute<TAttribute>();
        }

        /// <summary>
        /// 获取特性
        /// </summary>
        /// <typeparam name="TEntity">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <typeparam name="TAttribute">特性类型</typeparam>
        /// <param name="propertyExpression">属性表达式</param>
        public static TAttribute GetAttribute<TEntity, TProperty, TAttribute>(this Expression<Func<TEntity, TProperty>> propertyExpression) where TAttribute : Attribute
        {
            return GetAttribute<TAttribute>(propertyExpression);
        }

        /// <summary>
        /// 获取特性
        /// </summary>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <typeparam name="TAttribute">特性类型</typeparam>
        /// <param name="propertyExpression">属性表达式</param>
        public static TAttribute GetAttribute<TProperty, TAttribute>(this Expression<Func<TProperty>> propertyExpression) where TAttribute : Attribute
        {
            return GetAttribute<TAttribute>(propertyExpression);
        }

        #endregion

        #region GetAttributes(获取特性列表)

        /// <summary>
        /// 获取特性列表
        /// </summary>
        /// <typeparam name="TEntity">实体类型</typeparam>
        /// <typeparam name="TProperty">属性类型</typeparam>
        /// <typeparam name="TAttribute">特性类型</typeparam>
        /// <param name="propertyExpression">属性表达式</param>
        public static IEnumerable<TAttribute> GetAttributes<TEntity, TProperty, TAttribute>(this Expression<Func<TEntity, TProperty>> propertyExpression) where TAttribute : Attribute
        {
            var memberInfo = GetMember(propertyExpression);
            return memberInfo.GetCustomAttributes<TAttribute>();
        }

        #endregion

        #region Property(属性表达式)

        /// <summary>
        /// 创建属性表达式
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="propertyName">属性名,支持多级属性名，用句点分隔，范例：Customer.Name</param>
        public static Expression Property(this Expression expression, string propertyName)
        {
            if (propertyName.All(t => t != '.'))
                return Expression.Property(expression, propertyName);
            var propertyNameList = propertyName.Split('.');
            Expression result = null;
            for (int i = 0; i < propertyNameList.Length; i++)
            {
                if (i == 0)
                {
                    result = Expression.Property(expression, propertyNameList[0]);
                    continue;
                }
                result = result.Property(propertyNameList[i]);
            }
            return result;
        }

        /// <summary>
        /// 创建属性表达式
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="member">属性</param>
        public static Expression Property(this Expression expression, MemberInfo member)
        {
            return Expression.MakeMemberAccess(expression, member);
        }

        #endregion

        #region And(与表达式)

        /// <summary>
        /// 与操作表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression And(this Expression left, Expression right)
        {
            if (left == null)
                return right;
            if (right == null)
                return left;
            return Expression.AndAlso(left, right);
        }

        /// <summary>
        /// 与操作表达式
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            if (left == null)
                return right;
            if (right == null)
                return left;
            return left.Compose(right, Expression.AndAlso);
        }

        #endregion

        #region Or(或表达式)

        /// <summary>
        /// 或操作表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression Or(this Expression left, Expression right)
        {
            if (left == null)
                return right;
            if (right == null)
                return left;
            return Expression.OrElse(left, right);
        }

        /// <summary>
        /// 或操作表达式
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            if (left == null)
                return right;
            if (right == null)
                return left;
            return left.Compose(right, Expression.OrElse);
        }

        #endregion

        #region Value(获取lambda表达式的值)

        /// <summary>
        /// 获取lambda表达式的值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        public static object Value<T>(this Expression<Func<T, bool>> expression)
        {
            return expression.GetValue();
        }

        #endregion

        #region Equal(等于表达式)

        /// <summary>
        /// 创建等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression Equal(this Expression left, Expression right)
        {
            return left.Equal(right);
        }

        /// <summary>
        /// 创建等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression Equal(this Expression left, object value)
        {
            return left.Equal(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region NotEqual(不等于表达式)

        /// <summary>
        /// 创建不等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression NotEqual(this Expression left, Expression right)
        {
            return Expression.NotEqual(left, right);
        }

        /// <summary>
        /// 创建不等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression NotEqual(this Expression left, object value)
        {
            return left.NotEqual(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region Greater(大于表达式)

        /// <summary>
        /// 创建大于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression Greater(this Expression left, Expression right)
        {
            return Expression.GreaterThan(left, right);
        }

        /// <summary>
        /// 创建大于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression Greater(this Expression left, object value)
        {
            return left.Greater(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region GreaterEqual(大于等于表达式)

        /// <summary>
        /// 创建大于等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression GreaterEqual(this Expression left, Expression right)
        {
            return Expression.GreaterThanOrEqual(left, right);
        }

        /// <summary>
        /// 创建大于等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression GreaterEqual(this Expression left, object value)
        {
            return left.GreaterEqual(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region Less(小于表达式)

        /// <summary>
        /// 创建小于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression Less(this Expression left, Expression right)
        {
            return Expression.LessThan(left, right);
        }

        /// <summary>
        /// 创建小于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression Less(this Expression left, object value)
        {
            return left.Less(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region LessEqual(小于等于表达式)

        /// <summary>
        /// 创建小于等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="right">右操作数</param>
        public static Expression LessEqual(this Expression left, Expression right)
        {
            return Expression.LessThanOrEqual(left, right);
        }

        /// <summary>
        /// 创建小于等于运算表达式
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression LessEqual(this Expression left, object value)
        {
            return left.LessEqual(ExpressionHelper.Constant(value, left));
        }

        #endregion

        #region StartsWith(头匹配)

        /// <summary>
        /// 头匹配
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression StartsWith(this Expression left, object value)
        {
            return left.Call("StartsWith", new[] { typeof(string) }, value);
        }

        #endregion

        #region EndsWith(尾匹配)

        /// <summary>
        /// 尾匹配
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression EndsWith(this Expression left, object value)
        {
            return left.Call("EndsWith", new[] { typeof(string) }, value);
        }

        #endregion

        #region Contains(模糊匹配)

        /// <summary>
        /// 模糊匹配
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="value">值</param>
        public static Expression Contains(this Expression left, object value)
        {
            return left.Call("Contains", new[] { typeof(string) }, value);
        }

        #endregion

        #region Operation(操作)

        /// <summary>
        /// 操作
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="operator">运算符</param>
        /// <param name="value">值</param>
        public static Expression Operation(this Expression left, Operator @operator, object value)
        {
            switch (@operator)
            {
                case Operator.Equal:
                    return left.Equal(value);
                case Operator.NotEqual:
                    return left.NotEqual(value);
                case Operator.Greater:
                    return left.Greater(value);
                case Operator.GreaterEqual:
                    return left.GreaterEqual(value);
                case Operator.Less:
                    return left.Less(value);
                case Operator.LessEqual:
                    return left.LessEqual(value);
                case Operator.Starts:
                    return left.StartsWith(value);
                case Operator.Ends:
                    return left.EndsWith(value);
                case Operator.Contains:
                    return left.Contains(value);
            }
            throw new NotImplementedException();
        }

        /// <summary>
        /// 操作
        /// </summary>
        /// <param name="left">左操作数</param>
        /// <param name="operator">运算符</param>
        /// <param name="value">值</param>
        public static Expression Operation(this Expression left, Operator @operator, Expression value)
        {
            switch (@operator)
            {
                case Operator.Equal:
                    return left.Equal(value);
                case Operator.NotEqual:
                    return left.NotEqual(value);
                case Operator.Greater:
                    return left.Greater(value);
                case Operator.GreaterEqual:
                    return left.GreaterEqual(value);
                case Operator.Less:
                    return left.Less(value);
                case Operator.LessEqual:
                    return left.LessEqual(value);
            }
            throw new NotImplementedException();
        }

        #endregion

        #region Call(调用方法表达式)

        /// <summary>
        /// 创建调用方法表达式
        /// </summary>
        /// <param name="instance">调用的实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="values">参数值列表</param>
        public static Expression Call(this Expression instance, string methodName, params Expression[] values)
        {
            if (instance == null)
                throw new ArgumentNullException(nameof(instance));
            var methodInfo = instance.Type.GetMethod(methodName);
            if (methodInfo == null)
                return null;
            return Expression.Call(instance, methodInfo, values);
        }

        /// <summary>
        /// 创建调用方法表达式
        /// </summary>
        /// <param name="instance">调用的实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="values">参数值列表</param>
        public static Expression Call(this Expression instance, string methodName, params object[] values)
        {
            if (instance == null)
                throw new ArgumentNullException(nameof(instance));
            var methodInfo = instance.Type.GetMethod(methodName);
            if (methodInfo == null)
                return null;
            if (values == null || values.Length == 0)
                return Expression.Call(instance, methodInfo);
            return Expression.Call(instance, methodInfo, values.Select(Expression.Constant));
        }

        /// <summary>
        /// 创建调用方法表达式
        /// </summary>
        /// <param name="instance">调用的实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="paramTypes">参数类型列表</param>
        /// <param name="values">参数值列表</param>
        public static Expression Call(this Expression instance, string methodName, Type[] paramTypes, params object[] values)
        {
            if (instance == null)
                throw new ArgumentNullException(nameof(instance));
            var methodInfo = instance.Type.GetMethod(methodName, paramTypes);
            if (methodInfo == null)
                return null;
            if (values == null || values.Length == 0)
                return Expression.Call(instance, methodInfo);
            return Expression.Call(instance, methodInfo, values.Select(Expression.Constant));
        }

        #endregion

        #region Compose(组合表达式)

        /// <summary>
        /// 组合表达式
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="first">左操作数</param>
        /// <param name="second">右操作数</param>
        /// <param name="merge">合并操作</param>
        internal static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
        {
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
            return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }

        #endregion

        #region ToLambda(创建Lambda表达式)

        /// <summary>
        /// 创建Lambda表达式
        /// </summary>
        /// <typeparam name="TDelegate">委托类型</typeparam>
        /// <param name="body">表达式</param>
        /// <param name="parameters">参数列表</param>
        public static Expression<TDelegate> ToLambda<TDelegate>(this Expression body, params ParameterExpression[] parameters)
        {
            if (body == null)
                return null;
            return Expression.Lambda<TDelegate>(body, parameters);
        }

        #endregion

        #region ToPredicate(创建谓词表达式)

        /// <summary>
        /// 创建谓词表达式
        /// </summary>
        /// <typeparam name="T">委托类型</typeparam>
        /// <param name="body">表达式</param>
        /// <param name="parameters">参数列表</param>
        public static Expression<Func<T, bool>> ToPredicate<T>(this Expression body, params ParameterExpression[] parameters)
        {
            return ToLambda<Func<T, bool>>(body, parameters);
        }

        #endregion
    }

    /// <summary>
    /// 参数重绑定操作
    /// </summary>
    public class ParameterRebinder : ExpressionVisitor
    {
        /// <summary>
        /// 参数字典
        /// </summary>
        private readonly Dictionary<ParameterExpression, ParameterExpression> _map;

        /// <summary>
        /// 初始化参数重绑定操作
        /// </summary>
        /// <param name="map">参数字典</param>
        public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
        {
            _map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
        }

        /// <summary>
        /// 替换参数
        /// </summary>
        /// <param name="map">参数字典</param>
        /// <param name="exp">表达式</param>
        public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
        {
            return new ParameterRebinder(map).Visit(exp);
        }

        /// <summary>
        /// 访问参数
        /// </summary>
        /// <param name="parameterExpression">参数</param>
        protected override Expression VisitParameter(ParameterExpression parameterExpression)
        {
            if (_map.TryGetValue(parameterExpression, out var replacement))
                parameterExpression = replacement;
            return base.VisitParameter(parameterExpression);
        }
    }
}
